package com.ds.lens.flink.monitor.common.bo;

import com.ds.lens.data.common.constant.AggregatorEnum;
import com.ds.lens.data.common.constant.DetectionTypeEnum;
import com.ds.lens.data.common.constant.MonitorStateEnum;
import com.ds.lens.data.common.util.LensMQLBuilder;
import com.ds.lens.data.common.util.MapUtils;
import com.ds.lens.data.common.util.PastTimeRange;
import com.ds.lens.flink.monitor.monitorjob.function.detector.MonitorEventDetector;
import lombok.Builder;
import lombok.Getter;

import javax.persistence.Transient;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Getter
public class MonitorDefinition implements Serializable {
    private static final long serialVersionUID = 8750189860599193229L;
    private Long integrationId;
    private MonitorState monitorState;
    private String monitorName;
    private MonitorStateEnum state;
    private Long stateTime;
    private Integer windowType;
    private Integer windowTime;
    private Integer intervalTime;
    private Integer retiveDuration;
    private Integer retriveDelayTime;
    private String metricName;
    private AggregatorEnum metricAggr;
    private Map<String, Object> scope;
    private Map<String, Object> filters;
    private Map<String, Object> includes;
    private List<String> groupBys;
    private List<String> tags;
    @Transient
    private MonitorEventDetector detector;
    private EventNotificationDefinition notification;
    private Map<String, Object> levelThresholdMap;
    private transient String queryDSL;
    private Long versionTime;
    private Integer detectionMethod;

    @Builder
    private MonitorDefinition(
            MonitorState monitorState,
            String monitorName,
            Long integrationId,
            MonitorStateEnum state,
            Long stateTime,
            Integer windowType,
            Integer windowTime,
            Integer intervalTime,
            Integer retiveDuration,
            Integer retriveDelayTime,
            String metricName,
            AggregatorEnum metricAggr,
            Map<String, Object> scope,
            Map<String, Object> filters,
            List<String> groupBys,
            List<String> tags,
            MonitorEventDetector detector,
            EventNotificationDefinition notification,
            Map<String, Object> levelThresholdMap,
            Integer detectionMethod,
            Long versionTime) {
        this.monitorState = monitorState;
        this.monitorName = monitorName;
        this.integrationId = integrationId;
        this.state = state;
        this.stateTime = stateTime;
        this.windowType = windowType;
        this.windowTime = windowTime;
        this.intervalTime = intervalTime;
        this.retiveDuration = retiveDuration;
        this.retriveDelayTime = retriveDelayTime;
        this.metricName = metricName;
        this.metricAggr = metricAggr;
        this.scope = scope;
        this.filters = filters;
        this.includes = MapUtils.merge(new HashMap<>(), scope, filters);
        this.groupBys = groupBys;
        this.tags = tags;
        this.notification = notification;
        this.detector = detector;
        this.levelThresholdMap = levelThresholdMap;
        this.detectionMethod = (detectionMethod == null ? DetectionTypeEnum.STATIC_STATE.getCode() : detectionMethod);
        this.versionTime = versionTime;
        this.queryDSL = LensMQLBuilder.buildQueryDSL(metricName, metricAggr.name(), integrationId.toString(), includes,
                null, groupBys, new PastTimeRange(retiveDuration.longValue()),
                intervalTime != null ? intervalTime.longValue() : null, null);
        detector.setDefinition(this);
    }
}


